package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.model.user.UserPaidTrack;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencentcloudapi.tcaplusdb.v20190823.models.IdlFileInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;

	@Autowired
	private TrackStatMapper trackStatMapper;

	@Autowired
	private VodService vodService;

	@Autowired
	private AlbumInfoMapper albumInfoMapper;

	@Autowired
	private UserInfoFeignClient userInfoFeignClient;



	//新增声音
	/*
	保存声音 包括  1 添加声音基本信息  track_info
	   声音文件信息  大小  播放时长  类型等
	  order_num  声音排序字段  每次添加声音  值加一
	2 track_stat  每个声音有四个统计数据，四个统计数据初始化0
	3 album_info  声音所在专辑的include_track_count 包含声音数量加一
	 */


	@Transactional
	@Override
	public void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId) {

		//1  添加声音基本信息
		TrackInfo trackInfo = new TrackInfo();
		trackInfo.setUserId(userId);
		//状态默认审核通过
		trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);
		BeanUtils.copyProperties(trackInfoVo,trackInfo);


		//第二部分数据  到腾讯云找到  声音文件信息，大小  播放时长  类型
		//声音文件在腾讯云存储唯一标识
		String mediaFileId = trackInfo.getMediaFileId();
		//根据mediaFileId调用腾讯云对应接口获取声音文件信息
		TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackInfoTX(mediaFileId);
		String mediaUrl = trackMediaInfoVo.getMediaUrl();
		trackInfo.setMediaUrl(mediaUrl);
		Long size = trackMediaInfoVo.getSize();
		trackInfo.setMediaSize(size);
		String type = trackMediaInfoVo.getType();
		trackInfo.setMediaType(type);
		Float duration = trackMediaInfoVo.getDuration();
		trackInfo.setMediaDuration(duration);
//		order_num  表示声音在专辑里的排序  每次添加声音  值加一
		//要把专辑中最大的order_num取出来+1再放回去
       /*
       select order_num
       from track_info where track_info.album_id=1
       order by  order_num desc
       limit 1
        */
        LambdaQueryWrapper<TrackInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TrackInfo::getAlbumId,trackInfo.getAlbumId());
        wrapper.orderByDesc(TrackInfo::getOrderNum);
        wrapper.last(" limit 1");
        TrackInfo trackInfo1 = trackInfoMapper.selectOne(wrapper);
        Integer orderNumNew = 1;
        if(trackInfo1!=null){
            Integer orderNum = trackInfo1.getOrderNum();
            orderNumNew = orderNum+1;
        }
        trackInfo.setOrderNum(orderNumNew);
        trackInfoMapper.insert(trackInfo);
        //==============================================
		//2 track_stat
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PLAY);
		this.saveTrackStat(trackInfo.getId(),"0702");
		this.saveTrackStat(trackInfo.getId(),"0703");
		this.saveTrackStat(trackInfo.getId(),"0704");

//		//============================================================
		// //#3 album_info
		//   //## -- 修改操作，把声音所在专辑，include_track_count包含声音数量+1
		//   //根据专辑id查询专辑数据
		//   //获取声音数量值 + 1
		//   //调用方法修改
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		Integer includeTrackCount = albumInfo.getIncludeTrackCount();
		Integer includeTrackCount_new = includeTrackCount+1;
		albumInfo.setIncludeTrackCount(includeTrackCount_new);
		albumInfoMapper.updateById(albumInfo);
	}

	private void saveTrackStat(Long trackId,String trackType) {
		TrackStat trackStat = new TrackStat();
		trackStat.setTrackId(trackId);
		trackStat.setStatType(trackType);
		trackStat.setStatNum(0);
		this.trackStatMapper.insert(trackStat);
	}


	//分页查询声音列表
	@Override
	public IPage<TrackListVo> findUserTrackPage(Page<TrackListVo> trackInfoPage, TrackInfoQuery trackInfoQuery) {
		return trackInfoMapper.findUserTrackPageMapper(trackInfoPage,trackInfoQuery);
	}

	//删除声音接口
	@Override
	public void removeTrackInfo(Long id) {
		//album_info的include  字段-1
		TrackInfo trackInfo = trackInfoMapper.selectById(id);
		Long albumId = trackInfo.getAlbumId();
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		Integer includeTrackCount = albumInfo.getIncludeTrackCount();
		Integer inc_new = includeTrackCount-1;
		albumInfo.setIncludeTrackCount(inc_new);
		albumInfoMapper.updateById(albumInfo);

		//删除声音基本信息  track_info
		trackInfoMapper.deleteById(id);

		//删除track_stat
		trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId,id));

		//删除腾讯云声音文件
		//调用腾讯云接口实现
		vodService.removeTrackInfo(trackInfo.getMediaFileId());

	}

	//回显声音数据
	@Override
	public TrackInfo getTrackInfo(Long id) {
		TrackInfo trackInfo = trackInfoMapper.selectById(id);
		return trackInfo;
	}

	//修改声音
	@Override
	public void updateTrackInfo(Long id, TrackInfoVo trackInfoVo) {
//根据id修改声音
		//判断声音文件是否修改
		//根据声音id获取声音数据
		TrackInfo trackInfo = trackInfoMapper.selectById(id);
		String mediaFileId_datebase = trackInfo.getMediaFileId();

		BeanUtils.copyProperties(trackInfoVo,trackInfo);
		//比较数据库里存储的mediaFileId和页面传递过来的mediaFileId是否一致
		String mediaFileId_page = trackInfoVo.getMediaFileId();
		if(!mediaFileId_page.equals(mediaFileId_datebase)){
			//表示声音被修改
			//获取最新的声音文件数据
			TrackMediaInfoVo trackInfoTX = vodService.getTrackInfoTX(mediaFileId_page);
			trackInfo.setMediaSize(trackInfoTX.getSize());
			trackInfo.setMediaDuration(trackInfoTX.getDuration());
			trackInfo.setMediaUrl(trackInfoTX.getMediaUrl());
			trackInfo.setMediaType(trackInfoTX.getType());
			//删除云点播声音
//			vodService.removeTrackInfo(mediaFileId_datebase);
		}

		trackInfoMapper.updateById(trackInfo);

	}

	//根据专辑id获取声音信息
	@Override

	public IPage<AlbumTrackListVo> findAlbumTrackPage(Page<AlbumTrackListVo> listVoPage, Long albumId, Long userId) {

		//1 调用mapper的方法实现查询专辑下面声音列表
		IPage<AlbumTrackListVo> albumTrackListVoIPage = 	trackInfoMapper.findAlbumTrackPage(listVoPage,albumId);
		List<AlbumTrackListVo> albumTrackListVos = albumTrackListVoIPage.getRecords();

		//根据专辑id获取专辑数据
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		Assert.notNull(albumInfo,"专辑不能为空");
		//获取类型  0101--免费  0102-- vip免费  0103--付费
		String payType = albumInfo.getPayType();
		//2 判断用户是否登录
		if(userId==null){
			//表明用户未登录
			//3 如果用户没有登录 看免费专辑 vip免费和付费专辑可以观看试看声音
			if(!"0101".equals(payType)){
				//表示不是免费的类型，那么就只能看试看的部分，其余部分要收费，要把isShowPaidMark=true，表示这是付费部分
				Integer tracksForFree = albumInfo.getTracksForFree();//试看的集数
				List<AlbumTrackListVo> albumTrackListVoList = albumTrackListVos.stream().filter(albumTrackListVo ->
						albumTrackListVo.getOrderNum().intValue() > tracksForFree
				).collect(Collectors.toList());
//				albumTrackListVoList  ---要收费的部分
				if(!CollectionUtils.isEmpty(albumTrackListVoList)){
					albumTrackListVoList.forEach(albumTrackListVo -> {
						albumTrackListVo.setIsShowPaidMark(true);
					});
				}
			}
		}else{
			//表示用户登录
			//4 如果用户登录状态 判断用户是否是vip 如果是vip 可以观看vip免费的部分
			//付费专辑 ：用户登录了 付费 用户vip也要付费
			//如果用户购买了专辑或者声音 可以观看
			//如果用户购买了整个专辑 那么专辑里所有的声音都可以观看
			//如果用户购买专辑里面的某些声音 那么只有购买的这些声音可以观看

			//声明一个变量表示需不需要付费 ，默认为false
			boolean isNeedMoney = false;
			if("0102".equals(payType)){
				//表示vip免费
				Result<UserInfoVo> userInfoVoResult =
						userInfoFeignClient.getUserInfoVo(userId);
				UserInfoVo userInfoVo = userInfoVoResult.getData();
				Assert.notNull(userInfoVo,"用户数据为空");
				Integer isVip = userInfoVo.getIsVip();
				if(isVip==0){
					isNeedMoney=true;
				}
				Date vipExpireTime = userInfoVo.getVipExpireTime();
				if(isVip.intValue() == 1 && vipExpireTime.before(new Date())){
					isNeedMoney=true;
				}
			}else if ("0103".equals(payType)){
				isNeedMoney=true;
			}

			//如果专辑付费，统一处理
			if(isNeedMoney){
				//用户是否购买专辑或声音
				//获取需要付费的声音列表  除去试看的部分
				List<AlbumTrackListVo> albumTrackListVoList = albumTrackListVos.stream().filter(albumTrackListVo ->
						albumTrackListVo.getOrderNum().intValue() > albumInfo.getTracksForFree()
				).collect(Collectors.toList());
				//在需要付费的声音列表中 查询判断里面的声音是否购买过
				if(!CollectionUtils.isEmpty(albumTrackListVoList)){
					//获取声音id列表
					List<Long> trackIdList = albumTrackListVoList.stream().map(AlbumTrackListVo::getTrackId)
							.collect(Collectors.toList());
					//返回一个map集合 map的key是声音的id  value是Integer 0 表示没有购买过声音  1表示购买过
				Result<Map<Long,Integer>> result = 	userInfoFeignClient.userIsPaidTrack(userId,albumId,trackIdList);
					Map<Long, Integer> resultData = result.getData();
				albumTrackListVoList.forEach(albumTrackListVo -> {
					Long trackId = albumTrackListVo.getTrackId();
					Integer isBuy = resultData.get(trackId);
					if(isBuy==1) {
						//购买过
						albumTrackListVo.setIsShowPaidMark(false);
					}else{
						albumTrackListVo.setIsShowPaidMark(true);
					}
				});
				}
			}

		}





		return albumTrackListVoIPage;
	}



	//更新播放量
	@Override
	public void updatePlayNum(TrackStatMqVo trackStatMqVo) {
		Long trackId = trackStatMqVo.getTrackId();
		LambdaQueryWrapper<TrackStat> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(TrackStat::getTrackId,trackId);
		wrapper.eq(TrackStat::getStatType,"0701");
		TrackStat trackStat = trackStatMapper.selectOne(wrapper);
		Integer statNum = trackStat.getStatNum();
		trackStat.setStatNum(statNum+1);
		trackStatMapper.update(trackStat,wrapper);
	}

	//根据声音id获取购买声音列表的页面
	@Override
	public List<Map<String, Object>> findUserTrackPaidList(Long trackId) {
		//1 根据声音id获取声音数据(本集)
		TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
		//2 根据声音数据获取专辑id
		Long albumId = trackInfo.getAlbumId();
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);

		//远程调用：根据用户id+专辑id，查询用户在这个专辑购买过哪些声音,获取到购买过的声音id
		//1 2 3
		Long userId = AuthContextHolder.getUserId();
	Result<List<Long>> trackIdList = userInfoFeignClient.findUserPaidTrackId(userId,albumId);
	//获取用户购买过的声音列表
	List<Long> idListAlreadyBuy = trackIdList.getData();
		//3  查询专辑里面的所有声音(排除本集声音)
		//1 2 3 4 5 6 7 8
		LambdaQueryWrapper<TrackInfo> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(TrackInfo::getAlbumId,albumId);
		List<TrackInfo> trackInfoListOriginal = trackInfoMapper.selectList(queryWrapper);
		List<TrackInfo> trackInfoList = trackInfoListOriginal.stream().filter(trackInfo1 ->
				trackInfo1.getOrderNum() > trackInfo.getOrderNum()).collect(Collectors.toList());

		//4 排除所有声音购买过的声音 得到可以购买的声音列表

		ArrayList<TrackInfo> newTrackIdlist = new ArrayList<>();
		trackInfoList.stream().forEach(trackInfo1 -> {
			if(idListAlreadyBuy.size()!=0){
				idListAlreadyBuy.forEach(id->{
					boolean contains = trackInfoList.contains(id);
					if(!contains){
						newTrackIdlist.add(trackInfo1);
					}
				});
			}
			newTrackIdlist.add(trackInfo1);
		});
		//得到用户没有购买过的声音的id
		List<Long> NoBuyTrackIdList = newTrackIdlist.stream().map(TrackInfo::getId).collect(Collectors.toList());

		//5 封装集数

		ArrayList<Map<String, Object>> mapArrayList = new ArrayList<>();
		//(1)封装本集
		if(NoBuyTrackIdList.size()>=0){
			Map<String, Object> map = new HashMap<>();
			map.put("name","本集");
			map.put("price",albumInfo.getPrice());
			map.put("trackCount",0);
			mapArrayList.add(map);
		}
		//(2) 封装前10集
		//1 2 3 4 5 6 7 8  1集  后7集
		if(NoBuyTrackIdList.size() > 0 && NoBuyTrackIdList.size() <=10){
			Map<String, Object> map = new HashMap<>();
			map.put("name","后"+NoBuyTrackIdList.size()+"集");
			BigDecimal price = albumInfo.getPrice().multiply( new BigDecimal(NoBuyTrackIdList.size()));
			map.put("price",price);
			map.put("trackCount",NoBuyTrackIdList.size());
			mapArrayList.add(map);
		}

		//1 2 3 4 5 6 7 8 9 10 11 12 13 14 1集 后10集  后13集
		if(NoBuyTrackIdList.size() > 10){
			Map<String, Object> map = new HashMap<>();
			map.put("name","后10集");
			BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal("10"));
			map.put("price",price);
			map.put("trackCount",10);
			mapArrayList.add(map);
		}
		//1 2 3 4 5 6 7 8 9 10 11 12 13 14 1集 后10集  后13集
		if(NoBuyTrackIdList.size() > 10 && NoBuyTrackIdList.size() <=20){
			Map<String, Object> map = new HashMap<>();
			map.put("name","后"+NoBuyTrackIdList.size()+"集");
			BigDecimal price = albumInfo.getPrice().multiply( new BigDecimal(NoBuyTrackIdList.size()));
			map.put("price",price);
			map.put("trackCount",NoBuyTrackIdList.size());
			mapArrayList.add(map);
		}
		//1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1集 后10集  后20集 后22集
		if(NoBuyTrackIdList.size() > 20){
			Map<String, Object> map = new HashMap<>();
			map.put("name","后20集");
			BigDecimal price = albumInfo.getPrice().multiply( new BigDecimal("20"));
			map.put("price",price);
			map.put("trackCount",20);
			mapArrayList.add(map);
		}

		//1 2 3 4 5 6 7 8 9 10 11 12 13 14 1集 后10集  后13集
		if(NoBuyTrackIdList.size() >20 && NoBuyTrackIdList.size() <=30){
			Map<String, Object> map = new HashMap<>();
			map.put("name","后"+NoBuyTrackIdList.size()+"集");
			BigDecimal price = albumInfo.getPrice().multiply( new BigDecimal(NoBuyTrackIdList.size()));
			map.put("price",price);
			map.put("trackCount",NoBuyTrackIdList.size());
			mapArrayList.add(map);
		}

		//后30集
		if(NoBuyTrackIdList.size() >30){
			Map<String, Object> map = new HashMap<>();
			map.put("name","后30集");
			BigDecimal price = albumInfo.getPrice().multiply( new BigDecimal("30"));
			map.put("price",price);
			map.put("trackCount",30);
			mapArrayList.add(map);
		}
		if(NoBuyTrackIdList.size() >30 && NoBuyTrackIdList.size() <=50){
			Map<String, Object> map = new HashMap<>();
			map.put("name","后"+NoBuyTrackIdList.size()+"集");
			BigDecimal price = albumInfo.getPrice().multiply( new BigDecimal(NoBuyTrackIdList.size()));
			map.put("price",price);
			map.put("trackCount",NoBuyTrackIdList.size());
			mapArrayList.add(map);
		}
		if(NoBuyTrackIdList.size() >50){
			Map<String, Object> map = new HashMap<>();
			map.put("name","后50集");
			BigDecimal price = albumInfo.getPrice().multiply( new BigDecimal("50"));
			map.put("price",price);
			map.put("trackCount",50);
			mapArrayList.add(map);
		}


		return mapArrayList;
	}

	//查询当前购买声音的数据列表
	@Override
	public List<TrackInfo> findPaidTrackInfoList(Long itemId, Integer trackCount) {
		// 1 根据声音id 获取声音数据(本集)
		TrackInfo trackInfo = trackInfoMapper.selectById(itemId);
		System.out.println("1111kk"+trackInfo);
		//2 远程调用 ： 根据声音id  + 用户id  查询用户购买声音id列表
		//判断 trackCount = 0 表示只购买了本集 ，trackCount >0 后几集
		Long userId = AuthContextHolder.getUserId();
		Long albumId = trackInfo.getAlbumId();
		//用户已经购买过的声音id
		Result<List<Long>> userPaidTrackIdResult = userInfoFeignClient.findUserPaidTrackId(userId, albumId);
		List<Long> userPaidTrackId = userPaidTrackIdResult.getData();
		// 3 封装查询条件 查询专辑里面可以购买的声音
		//专辑id
		//大于本集声音  orderNum
		//声音id不在购买过声音id列表里面  notin
		List<TrackInfo> trackInfoList = new ArrayList<>();
		if(trackCount > 0){
			LambdaQueryWrapper<TrackInfo> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(TrackInfo::getAlbumId,albumId);
			wrapper.gt(TrackInfo::getOrderNum,trackInfo.getOrderNum());
			if(!CollectionUtils.isEmpty(userPaidTrackId)){
				wrapper.notIn(TrackInfo::getId,userPaidTrackId);
			}

			//limit  trackCount
			wrapper.last(" limit "+trackCount);
			//查询专辑id里的声音
		  trackInfoList = trackInfoMapper.selectList(wrapper);
		}else{
			trackInfoList.add(trackInfo);
			return trackInfoList;
		}
		return trackInfoList;
	}
}
